<?php

App::uses('AppController', 'Controller');

/**
 * Description of OrganisationController
 *
 * @author Francis Adu-Gyamfi
 */
class OrganisationController extends AppController {

    public $uses = array('Organisation', 'SubscriptionType', 'OrganisationSetting', 
        'OrganisationAccount', 'Member', 'OrganisationMember', 'OrganisationCounter', 'OrganisationGroupType');
    public $components = array('AccountEmail');
    public $layout = "admin";

    public function beforeFilter() {
        parent::beforeFilter();

        $this->autoRender = false;
    }
    
    public function listAll() {
        $organisations = $this->Organisation->find('list', array(
            'conditions' => array(
                'active' => 1
            ),
            'order' => array('name')
        ));
        
        return $this->_response($organisations);
    }
    
    public function create() {
        $rules = array(
            'required' => 'org_name, org_type_id, org_subscription_type_id, member_account_id'
        );
        
        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        $account = array(
            'name' => $org_name,
            'organisation_type_id' => $org_type_id,
            'slug' => strtolower(Inflector::slug($org_name, "-")),
            'address' => $org_address,
            'email' => $org_email,
            'phone' => $org_phone,
            'website' => $org_website,
            'city' => $org_city,
            'country' => $org_country,
            'state' => $org_state,
            'post_code' => $org_post_code,
            'subscription.type_id'=>$org_subscription_type_id,
            //'first_name' => $account_fname,
            //'last_name' => $account_lname,
            //'gender' => $account_gender,
            //'dob' => $account_dob,
            //'email' => $account_username, //it's an email, required
            'member_account_id' => $member_account_id
            /*'account.username' => $account_username,
            'account.password' => $account_password*/
        );


        $response = $this->Organisation->createOrganisation($account);
        
        if( $response['status'] == 'success' ) {
            $this->AccountEmail->emailOrganisationActivation($response['organisation_account_id']);
        }
        
        return $this->_response($response);
        
    }
    
    public function activate() {
        $rules = array(
            'required' => 'organisation_id, activate',
            'numeric' => 'organisation_id, activate',
            'regex' => array(
                'activate' => array(
                    'rule' => '/[01]/',
                    'message' => "'activate' should be either a 0 or 1."
                )
            )
        );
        
        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $response = $this->Organisation->activate($organisation_id, $activate);
        
        return $this->_response($response);
    }

    public function setting() {
        $rules = array(
            'required' => 'organisation_id, key'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        $setting = $this->Organisation->OrganisationSetting->getSetting($organisation_id, $key);

        return $this->_response(array('value' => $setting['OrganisationSetting']['value']));
    }
    
    public function settings($action = 'fetch') {
        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        if( $action == 'populate' ) {
            $settings = $this->Organisation->populateSettings($organisation_id);
            
            return $this->_response(array('status' => $settings ? 'success' : 'failed', 'settings' => $settings));
        } 
        
        else if( $action == 'fetch' ) {
            $settings = $this->Organisation->getSettings($organisation_id);
            
            return $this->_response($settings);
        }
    }
    
    public function category($action = null) {
        
        if( $action == "update" ) {
            return $this->category_update();
        }
        
        else if( $action == "change" ) {
            return $this->category_change();
        }
        
        else if( $action == "delete" ) {
            $data = $this->request->data;
            $response = ClassRegistry::init('OrganisationMemberCategory')->deactivate($data['organisation_id'], $data['category_id']);
            
            return $this->_response($response);
        }
        
        else {
            return $this->category_fetch();
        }
    }
    
    private function category_fetch() {
        $data = $this->request->data;
        $validated = $this->_validateParams(array(
            'required' => 'organisation_id, category_id'
        ), $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $category = ClassRegistry::init('OrganisationMemberCategory')->find('first', array(
            'contain' => array(
                'OrganisationMemberCategorySetting' => array(
                    'MemberCategorySetting' => array(
                        'order' => array('MemberCategorySetting.position')
                    )
                )
            ),
            'conditions' => array(
                'OrganisationMemberCategory.organisation_id' => $organisation_id,
                'or' => array(
                    'OrganisationMemberCategory.id' => $category_id,
                    'OrganisationMemberCategory.slug' => $category_id
                )
            )
        ));
        
        return $this->_response($category);
    }
    
    public function categories() {
        $data = $this->request->data;
        $validated = $this->_validateParams(array(
            'required' => 'organisation_id'
        ), $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $categories = ClassRegistry::init('OrganisationMemberCategory')->getCategories($organisation_id);
        
        return $this->_response($categories);
    }
    
    private function category_update() {
        $data = $this->request->data;
        $validated = $this->_validateParams(array(
            'required' => 'organisation_id, category'
        ), $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $response = ClassRegistry::init('OrganisationMemberCategory')->updateCategory($category);
        
        return $this->_response($response);
    }
    
    private function category_change() {
        $data = $this->request->data;
        $validated = $this->_validateParams(array(
            'required' => 'organisation_id, category_id, member_id'
        ), $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $response = $this->OrganisationMember->changeCategory($organisation_id, $category_id, $member_id);
        
        return $this->_response($response);
    }

    public function stats() {

        $data = $this->request->data;
        
        $validated = $this->_validateParams(array('required' => 'organisation_id'), $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }
        
        $base = array(
            array(
                'category_name' => 'All Members',
                'members' => $this->OrganisationMember->getTotalMembers($data['organisation_id'])
            )
        );

        $cat_stats = $this->OrganisationMember->getStatsByCategory($data['organisation_id']);

        $stats = array_merge($base, $cat_stats);

        return $this->_response($stats);
    }
    
    public function preferences() {
        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $preferences = $this->OrganisationSetting->find('all', array(
            'conditions' => array(
                'OrganisationSetting.organisation_id' => $organisation_id
            )
        ));
        
        return $this->_response($preferences);
    }

    public function index() {

        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        if (!isset($contain)) {
            $contain = array();
        }

        $organisation = $this->Organisation->getOrganisationInfo($organisation_id, $contain);

        return $this->_response($organisation);
    }

    public function update() {

        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id, info'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        $response = $this->Organisation->updateProfile($organisation_id, $info);

        return $this->_response(array(
                    'status' => $response ? 'success' : 'failed',
                    'message' => $response ? 'Profile Save Successful' : 'Failed To Save Profile Due To Database Error'
        ));
    }

    public function accounts($action = '') {
        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
            
        if( $action == 'batch_update' ) {
            if( !isset($data['accounts']) ) {
                return array('status' => 'failed', 'message' => 'Missing parameter \'accounts\' required for batch update ');
            }
            
            $created = array();
            $updated = array();
            
            foreach($data['accounts'] as $account) {
                if( !empty($account['member_id']) && !empty($account['organisation_role_id']) && empty($account['org_account_id']) ) {
                    $response = $this->OrganisationAccount->addAccount($organisation_id, $account['member_id'], $account['organisation_role_id']);
                    
                    if( $response['status'] == 'success' ) {
                        $account['org_account_id'] = $response['organisation_account_id'];
                        
                        if( isset($response['temp_member_account_id']) ) {
                            $this->AccountEmail->emailMemberAccountActivation($response['temp_member_account_id']);
                        }
                        
                        else if( $response['code'] == 'CA004' ) {
                           $this->AccountEmail->emailOrganisationAccountActivation($response['organisation_account_id']);
                        }
                    }
                    
                    $created[] = $response;
                }
                
                if( !empty($account['org_account_id']) && !empty($account['organisation_role_id']) ) {
                    $updated[] = $this->OrganisationAccount->updateAccountRole($organisation_id, $account['org_account_id'], $account['organisation_role_id']);
                }
            }
            
            return $this->_response(array('status' => 'success', 'message' => 'batch update processed', 'created' => $created, 'updated' => $updated));
        }

        else {
            $organisation_accounts = $this->OrganisationAccount->getOrganisationAccounts($organisation_id);

            return $this->_response($organisation_accounts);
        }
    }
    
    /**
     * 
     * @return type
     * @deprecated since version 0.2.5
     */
    public function checkOldPass() {

        $status = $this->OrganisationAccount->validatePass($_POST['pass'],$_POST['account_id']);

        return $this->_response($status);
    }
    
    /**
     * Returns information about a specific organisation account if called via
     * a GET request.
     * 
     * Updates information about a specific account if called via a POST request
     * 
     * @return json
     */
    public function account($action = 'get') {
        
        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        if( $action == 'get' ) {
            
            $account = $this->OrganisationAccount->getOrganisationAccount($data['organisation_id'], $data['account_id']);

            return $this->_response($account);
        }
        
        else if( $action == 'list' ) {
            $organisation_accounts = $this->OrganisationAccount->getOrganisationAccounts($data['organisation_id']);

            return $this->_response($organisation_accounts);
        }
        
        else if( $action == 'create' || $action == 'update' ) {
            $account = $this->OrganisationAccount->updateAccount($data['organisation_id'], $data);

            return $this->_response($account);
        }
        
        else if( $action == 'delete' ) {
            $account = $this->OrganisationAccount->trash($data['organisation_id'], $data['account_id']);
            
            return $this->_response(array('status' => $account ? 'success' : 'failed'));
        }
        
        else if( $action == "checkAvailability" ) {
            $info = $this->OrganisationAccount->checkAvailability($data['organisation_id'], $data['username']);
            
            return $this->_response($info);
        }
        
        else if( $action == 'activate' ) {
            $response = $this->OrganisationAccount->activateAccount($data['organisation_id'], $data['account_username'], $data['validation_hash']);
        
            return $this->_response($response);
        }
        
        else if( $action == "reset_password" ) {
            if( !isset($data['reset_url']) ) {
                return $this->_response(array('status' => 'failed', 'message' => "Missing parameter 'reset_url' not passed"));
            }
            
            $response = $this->AccountEmail->emailPasswordReset($data['username'], $data['reset_url']);
            
            return $this->_response($response);
        }
        
        else if( $action == "change_password" ) {
            $response = $this->OrganisationAccount->changePassword($data['organisation_id'], $data['account_id'], $data['old_password'], $data['new_password']);
            
            if( $response['status'] == 'success' ) {
                $this->AccountEmail->emailPasswordChangeNotification($data['account_id']);
            }
            
            return $this->_response($response);
        }
        
        else if( $action == 'lookup' ) {
            $response = $this->OrganisationAccount->lookupAccount($data['organisation_id'], $data['term']);
            
            return $this->_response($response);
        }
        
        else if( $account == 'batch_update' ) {
            
        }
    }
    
    public function role($action = 'fetch') {
        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        if( $action == 'list' ) {

            $role = ClassRegistry::init('OrganisationRole')->find('all', array(
                'conditions' => array(
                    'OrganisationRole.organisation_id' => $data['organisation_id'],
                    'OrganisationRole.active' => 1
                ),
                'order' => array('OrganisationRole.name'),
                'recursive' => -1
            ));

            $response = array('status' => 'success', 'roles' => $role);

            return $this->_response($response);
        }
        
        else if( $action == 'fetch' ) {
        
            $role = ClassRegistry::init('OrganisationRole')->find('first', array(
                'contain' => array('OrganisationRoleModule'),
                'conditions' => array(
                    'OrganisationRole.organisation_id' => $data['organisation_id'],
                    'OrganisationRole.id' => $data['role_id'],
                    'OrganisationRole.active' => 1
                )
            ));
            
            if( $role ) {
                $response = array('status' => 'success', 'role' => $role);
            } else {
                $response = array('status' => 'failed', 'message' => 'Organisation Role Not Found');
            }
           
            return $this->_response($response);
        }
        
        else if( $action == 'update' ) {
            $response = ClassRegistry::init('OrganisationRole')->updateRole($data);
            
            return $this->_response($response);
        }
        
        else if( $action == 'delete' ) {
            $response = ClassRegistry::init('OrganisationRole')->markDeleted($data['organisation_id'], $data['role_id']);
            
            return $this->_response($response);
        }
    }

    public function login() {
        
        $this->autoRender = false;

        $rules = array(
            'required' => 'username, password'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        $validAccount = $this->OrganisationAccount->attempt_login($data['username'], $data['password']);

        if ($validAccount) {
            return $this->_response(array(
                'status' => 'success',
                'account' => $validAccount
            ));
        } else {
            return $this->_response(array(
                'status' => 'failed',
                'message' => 'Login failed. Account information invalid or organisation not active'
            ));
        }

        return $this->_response(array(
            'status' => 'failed',
            'message' => 'Invalid request parameters passed'
        ));
    }
    
    public function manage() {
        
        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id, member_account_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        $validAccount = $this->OrganisationAccount->manage($data['organisation_id'], $data['member_account_id']);

        if ($validAccount) {
            return $this->_response(array(
                'status' => 'success',
                'account' => $validAccount
            ));
        } else {
            return $this->_response(array(
                'status' => 'failed',
                'message' => 'Login failed. Account information invalid or organisation not active'
            ));
        }

        return $this->_response(array(
            'status' => 'failed',
            'message' => 'Invalid request parameters passed'
        ));
    }
    
    public function memberCategory() {
        $rules = array(
            'required' => 'organisation_id, category_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $category = ClassRegistry::init('OrganisationMemberCategory')->getCategory($organisation_id, $category_id);
        
        return $this->_response(array('status' => 'success', 'data' => $category));
    }

    public function member() {

        $rules = array(
            'required' => 'member_id, organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        $association = $this->OrganisationMember->getAssociation($organisation_id, $member_id);

        if ($association) {

            $member_data = $association;

            return $this->_response($member_data);
        }

        return array(
            'status' => 'failed',
            'message' => 'Member Not Associated With Organisation'
        );
    }

    public function getMembersTotal() {
        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        if (!isset($status)) {
            $status = 'member';
        }

        $members = $this->OrganisationMember->getTotalMembers($organisation_id, $status);

        return $this->_response($members);
    }

    public function createMember() {

        $data = $this->request->data;

        if (isset($data['Member'])) {
            $this->autoRender = false;
            
            $result = $this->OrganisationMember->saveAndUpdateProfile($data);
            

            return $this->_response(array(
                'status' => $result ? 'success' : 'failed',
                'message' => $result ? 'Profile Updated Successfully' : 'Profile Update Failed',
                'result' => $result,
                'data' => $data
            ));
        }
    }
    
    public function registerMember() {
        if( !$this->request->is('post') ) {
            return array('status' => 'failed', 'message' => 'Request format invalid');
        }
        
        $this->autoRender = false;
        
        $rules = array(
            'required' => 'organisation_id, category_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }
        
        // force set the data source
        $data['source'] = 'registration';

        extract($data);
        
        $result = $this->OrganisationMember->createMember($organisation_id, $category_id, $data);
        
        if( isset($result['member']) ) {
            //TODO: Send confirmation email to members who register
            
            return $this->_response(array_merge(array('status' => 'success'), $result));
        }
                   
        return $this->_response(array('status' => 'failed', 'message' => 'Registration process failed'));
    }

    public function removeMember() {

        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id, member_ids'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        $result = $this->OrganisationMember->updateAll(array('active' => 0), 
                array('OrganisationMember.organisation_id' => $organisation_id, 'OrganisationMember.member_id' => $member_ids));

        return $this->_response(array(
                    'status' => $result ? 'success' : 'failed',
                    'message' => $result ? 'Member(s) successfully removed' : 'Member removal failed.'
        ));
    }

    /**
     * returns the view for when a member is searched
     */
    public function find_member() {

        $rules = array(
            'required' => 'organisation_id, organisation_member_category_id',
            'numeric' => 'limit, offset'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        if (!isset($term)) {
            $term = '';
        }
        if (!isset($limit)) {
            $limit = 50;
        }
        if (!isset($offset)) {
            $offset = 0;
        }
        if (!isset($sort_order)) {
            $sort_order = 'alpha';
        }

        $members = $this->OrganisationMember->findMembersBySearchTerm($organisation_id, $term, $organisation_member_category_id, $offset, $limit, $sort_order);

        return $this->_response($members);
    }
    
    public function members($action = 'list') {
        $response = array();
        
        switch($action) {
            case 'list':
                $response = $this->_listMembers();
                break;
        }
        
        return $this->_response($response);
    }
    
    public function _listMembers() {
        $this->autoRender = false;
        
        $limit = 5;
        
        $rules = array(
            'required' => 'organisation_id, term',
            'numeric' => 'limit'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $result = $this->OrganisationMember->find('all', array(
            'contain' => array(
                'Member' => array(
                    'fields' => array('Member.id', 'Member.first_name', 'Member.last_name'),
                    'MemberImage' => array(
                        'limit' => 1,
                        'order' => array('MemberImage.id' => 'desc')
                    )
                )
            ),
            'fields' => array('OrganisationMember.id', 'OrganisationMember.organisation_no'),
            'conditions' => array(
                'OR' => array(
                    "CONCAT(Member.first_name, ' ', Member.last_name, ' ', OrganisationMember.organisation_no) LIKE " => "%$term%",
                    "CONCAT(Member.last_name, ' ', Member.first_name, ' ', OrganisationMember.organisation_no) LIKE " => "%$term%"
                ),
                'OrganisationMember.organisation_id' => $organisation_id
            ),
            'order' => array('Member.first_name', 'Member.last_name'),
            'limit' => $limit
        ));
        
        $response = array();
        
        foreach($result as $row) {
            $response[] = array(
                'id' => $row['Member']['id'],
                'label' => $row['Member']['first_name'] . " " . $row['Member']['last_name'],
                'member_id' => $row['Member']['id'],
                'organisation_member_id' => $row['OrganisationMember']['id'],
                'organisation_no' => $row['OrganisationMember']['organisation_no'],
                'member_image' => isset($row['Member']['MemberImage'][0]) ? $row['Member']['MemberImage'][0]['thumb_url'] : '',
                'member_image_full' => isset($row['Member']['MemberImage'][0]) ? $row['Member']['MemberImage'][0]['url'] : ''
            );
        }
        
        return $response;
    }

    public function member_count() {
        $this->autoRender = false;
        
        $rules = array(
            'required' => 'organisation_id, type'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        $count = $this->OrganisationCounter->getCount($organisation_id, $type);

        return $this->_response($count);
    }

    public function member_stats() {
        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id, stats_type'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);

        if ($stats_type == "charts" && isset($chart_types)) {
            $charts = array();

            foreach ($chart_types as $chart_type) {
                switch ($chart_type) {
                    case 'recent_members':
                        $members = $this->OrganisationMember->recentStatsByStatusType($organisation_id, 'member');

                        $results = Hash::combine($members, '{n}.0.dt', '{n}.0.count');
                        $charts[$chart_type] = Hash::sort($results, '{n}', 'desc');
                        break;

                    case 'recent_visitors':
                        $members = $this->OrganisationMember->recentStatsByStatusType($organisation_id, 'visitor');

                        $results = Hash::combine($members, '{n}.0.dt', '{n}.0.count');
                        $charts[$chart_type] = Hash::sort($results, '{n}', 'desc');
                        break;
                }
            }

            return $this->_response(array(
                'status' => 'success',
                'charts' => $charts
            ));
        }

        return $this->_response(array(
                    'status' => 'failed',
                    'message' => 'Invalid Parameters Passed'
        ));
    }
    
    /**
     * Changes the status of a member between 'member', 'status' and 'deceased'
     * 
     * @return json
     * @deprecated since version 0.2.5
     */
    public function changeStatus() {
        
        $rules = array(
            'required' => 'organisation_id, member_id, status'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $saved = $this->OrganisationMember->updateAll(array('OrganisationMember.status' => $status), 
                array('OrganisationMember.organisation_id' => $organisation_id, 'OrganisationMember.member_id' => $member_id));
        
        return $this->_response(array('status' => $saved ? 'success' : 'failed', 'message' => $saved ? 'Status changed' : 'Failed to change status'));
    }

    public function activityFeed() {
        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $self = $this;
        
        $member_data = Cache::remember('_' . $organisation_id, function() use ($self, $organisation_id) {
            return $self->OrganisationMember->find('all', array(
                'contain' => array(
                    'Member', 
                    'OrganisationMemberImage' => array(
                        'conditions' => array('OrganisationMemberImage.member_image_id IS NOT' => null),
                        'MemberImage'
                    ), 
                    'Approver' => array(
                        'MemberAccount' => array(
                            'Member' => array(
                                'fields' => array('first_name', 'middle_name', 'last_name')
                            )
                        )
                    )
                ),
                'conditions' => array(
                    'OrganisationMember.organisation_id' => $organisation_id,
                    'OrganisationMember.active' => 1
                ),
                'order' => array('OrganisationMember.created' => 'desc'),
                'limit' => isset($limit) ? $limit : 10,
                'offset' => isset($offset) ? $offset : 0
            ));
        }, 'activity_feed');
        
        foreach($member_data as &$m) {
            if( isset($m['Approver']['MemberAccount']['Member']) ) {
                $m['Approver'] = $m['Approver']['MemberAccount']['Member'];
            }
        }
        
        return $this->_response($member_data);
    }
    
    /**
     * Marks a member as approved
     * 
     * @return type
     */
    public function joinApproval() {
        $this->autoRender = false;

        $rules = array(
            'required' => 'organisation_id, member_id, organisation_account_id, action'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $orgMember = $this->OrganisationMember->getAssociation($organisation_id, $member_id);
        
        if( $action == "approve" ) {
            $response = $this->OrganisationMember->approve($organisation_id, $member_id, $organisation_account_id);
        }
        
        else if( $action == "decline" ) {
            $response = $this->OrganisationMember->decline($organisation_id, $member_id, $organisation_account_id);
        }
        
        $response['member'] = $orgMember;
        
        return $this->_response($response);
    }
    
    public function join() {
        
        $data = $this->request->data;
        
        $rules = array(
            'required' => 'organisation_id, member_id'
        );
        
        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $response = $this->OrganisationMember->createPublicAssociation($organisation_id, $member_id);
        
        return $this->_response($response);
    }
    
    /**
     * 
     */
    public function public_list() {
        $this->autoRender = false;
        
        $rules = array(
            'required' => 'member_id, offset, limit',
            'numeric' => 'member_id, offset, limit'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $organisations = $this->Organisation->publicList($member_id, $offset, $limit);
        
        return $this->_response($organisations);
    }
    
    public function birthdays() {
        $this->autoRender = false;
        
        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $self = $this;
        
        $members = Cache::remember('_' . $organisation_id, function() use ($self, $organisation_id) {
            return $self->OrganisationMember->upcomingBirthdays($organisation_id);
        },'birthdays');
        
        return $this->_response(array('status' => 'success', 'data' => $members));
    }
    
    public function notifications($action = 'recent') {
        $this->autoRender = false;
        
        $limit = 50;
        $offset = 0;
        $notification_type_id = null;
        
        $rules = array(
            'required' => 'organisation_id',
            'numeric' => 'read, notification_id, notification_type_id, limit, offset'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $OrganisationNotification = ClassRegistry::init('OrganisationNotification');
        $response = null; $list = null;
        
        switch($action) {
            case 'all':
            case 'recent':
                $list = $OrganisationNotification->getList($organisation_id, -1, $limit, $offset);
                break;
            case 'unread':
            case 'read':
                $list = $OrganisationNotification->getList($organisation_id, $read);
                break;
            case 'mark_all_read':
                $response = $OrganisationNotification->markAllRead($organisation_id, $read);
                break;
            case 'mark_read':
                $response = $OrganisationNotification->markRead($organisation_id, $notification_type_id, $notification_id, $read);
                break;
        }
        
        if( $response ) {
            return $this->_response($response);
        }
        
        if( $list ) {
            return $this->_response(array(
                'status' => 'success',
                'list' => $list 
            ));
        }
        
        return $this->_response(array(
            'status' => 'failed',
            'message' => 'No data found for request',
            'list' => $list
        ));
    }
    
    public function remove() {
        $this->autoRender = false;
        
        $rules = array(
            'required' => 'organisation_id, member_account_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $response = $this->Organisation->remove($organisation_id, $member_account_id);
        
        if( $response['status'] == 'success' ) {
            $this->AccountEmail->emailOrganisationDeactivation($organisation_id, $member_account_id);
        }
        
        return $this->_response($response);
    }
    
    public function general_stats() {
        
        $this->autoRender = false;
        
        $rules = array(
            'required' => 'organisation_id'
        );

        $data = $this->request->data;

        $validated = $this->_validateParams($rules, $data);

        if ($validated != "NO_ERROR") {
            return $validated;
        }

        extract($data);
        
        $group_stats = $this->OrganisationGroupType->group_stats($data['organisation_id']);
        $gender_stats = $this->OrganisationMember->genderStats( $data['organisation_id'] );
        $employment_stats = $this->OrganisationMember->employmentStats( $data['organisation_id'] );
        $marital_stats = $this->OrganisationMember->maritalStatusStats( $data['organisation_id'] );
        $dayname_stats = $this->OrganisationMember->dayOfBirthStats( $data['organisation_id'] );
        $monthname_stats = $this->OrganisationMember->monthOfBirthStats( $data['organisation_id'] );
        
        $final = array(
            'Member Statistics' => array_merge($gender_stats, $marital_stats, $employment_stats, $monthname_stats, $dayname_stats), 
            'Small Groups Stats' => $group_stats 
        );
        
        return $this->_response($final);
    }
}
